package helper

import "cmp"

// Select 选取集合中的元素
func Select[T, E any](source []T, selector func(T) E) []E {
	result := make([]E, 0, len(source))
	for _, item := range source {
		result = append(result, selector(item))
	}
	return result
}

// SelectMany 批量选择
func SelectMany[T, E any](source []T, selector func(T) []E) []E {
	result := make([]E, 0, len(source))
	for _, item := range source {
		result = append(result, selector(item)...)
	}
	return result
}

// SelectMap 从map中选择元素
func SelectMap[T comparable, E, F any](source map[T]E, selector func(T, E) F) []F {
	result := make([]F, 0, len(source))
	for k, v := range source {
		result = append(result, selector(k, v))
	}
	return result
}

// Any 是否有符合条件的元素
func Any[T any](source []T, filter func(T) bool) bool {
	for _, item := range source {
		if filter(item) {
			return true
		}
	}
	return false
}

// Where 根据条件过滤集合
func Where[T any](source []T, filter func(T) bool) []T {
	var result []T
	for _, item := range source {
		if filter(item) {
			result = append(result, item)
		}
	}
	return result
}

// FirstOrDefault 取第一个命中条件的元素
func FirstOrDefault[T any](source []T, filter func(T) bool) T {
	var d T
	for _, item := range source {
		if filter(item) {
			return item
		}
	}
	return d
}

// Max 取最大值
func Max[T any, E cmp.Ordered](source []T, selector func(T) E) E {
	if len(source) == 0 {
		var def E
		return def
	}
	m := new(E)
	for _, item := range source {
		if r := selector(item); m == nil || r > *m {
			m = &r
		}
	}
	return *m
}

// SkipAndTake 跳过并取指定数量的元素
func SkipAndTake[T any](source []T, skip int64, take int64) []T {
	r := make([]T, 0, take)
	for i := int(skip); i < len(source); i++ {
		r = append(r, source[i])
	}
	return r
}
